package main

import (
	"context"
	"fmt"
	"sync"
	"time"
)

var wg sync.WaitGroup

//func cpuInfo(closeChan chan struct{}) {
//	defer wg.Done()
//	for {
//		select {
//		case <-closeChan:
//			fmt.Println("退出cpu监控")
//			return
//		default:
//			<-time.After(2 * time.Second)
//			fmt.Println("cpu的信息")
//		}
//	}
//}

func cpuInfo(ctx context.Context) {
	fmt.Printf("tranceid:%s\r\n", ctx.Value("tranceid"))
	defer wg.Done()
	for {
		select {
		case <-ctx.Done():
			fmt.Println("退出cpu监控")
			return
		default:
			<-time.After(2 * time.Second)
			fmt.Println("cpu的信息")
		}
	}
}

func main() {
	wg.Add(1)

	//ch := make(chan struct{})
	//go cpuInfo(ch)
	//time.Sleep(10 * time.Second)
	//close(ch)

	//context包提供了三种函数， withCancel， WithTimeout, WithValue
	//如果你的goroutine， 函数中，如果希望被控制， 超时、传值，但是我不希望影响我原来的接口信息的时候，函数参数中第一个参数就尽量的要加上一个ctx

	//1.父context cancel()，所有子context都会调用cancel()，都会被监控到
	//WithCancel 手动取消
	//ctx1, cancel1 := context.WithCancel(context.Background())
	//ctx2, cancel2 := context.WithCancel(ctx1)
	//go cpuInfo(ctx2)
	//time.Sleep(10 * time.Second)
	//cancel1()

	//2. timeout 主动超时
	ctx, _ := context.WithTimeout(context.Background(), 10*time.Second)
	//go cpuInfo(ctx)
	//3. WithDeadline 在时间点cancel

	//4. withValue
	ctx1 := context.WithValue(ctx, "tranceid", "dsafsag")
	go cpuInfo(ctx1)

	wg.Wait()
	fmt.Println("监控完成")
}
